interface data {
    value: any,
    delay: number,
    immediate: boolean
}

// 在指令的生命钩子执行的函数
// 从binding中解构获取blnding.value,也就是(v-debounce="{...}")中传递的值
const debounce = (el: any, { value }: data) => {
    let timer: number
    // 设置默认值
    const delay = value.delay || 2000
    const immediate = value.immediate || true
    if (immediate) {
        let flag = true
        // 在点击种类的高频事件中实现防抖
        el.addEventListener('click', () => {
            clearTimeout(timer);
            if (flag) {
                typeof value.fn === 'function' && value.fn();
                flag = false
            }
            timer = setTimeout(() => {
                flag = true
            }, delay) //可通过指令传值设置计时时间
        })
    } else {
        el.addEventListener('click', () => {
            clearTimeout(timer);
            timer = setTimeout(() => {
                typeof value === 'function' && value();
            }, delay) //可通过指令传值设置计时时间
        })
    }

}

const debouncePlugin = {
    install(app: any, options: any) {
        app.directive('debounce', {
            // binding:数据对象
            //   + arg:传给指令的参数   v-xxx:n -> arg:"n"
            //   + modifiers:修饰符对象 v-xxx.stop -> modifiers:{stop:true}
            //   + value:指令绑定的值   v-xxx="1+1" -> value:2
            //   + oldValue:之前绑定的值
            mounted: (el: any, binding: any) => {
                // binging.value有三个参数:
                // 1. fn:调用的回调,必须参数
                // 2. delay:延迟时间,可选参数(默认值为2000)
                // 3. immediate:节流或者先防抖再执行,可选参数(默认值为true)
                debounce(el, binding);
            },
        })
    }
}

export default debouncePlugin